package com.tally.server.service;

import com.tally.server.domain.Comment;
import com.tally.server.domain.CommentExample;
import com.tally.server.dto.CommentDTO;
import com.tally.server.dto.PageDTO;
import com.tally.server.enums.DeletedStatusEnum;
import com.tally.server.mapper.CommentMapper;
import com.tally.server.utils.CopyUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Date;
import java.util.stream.Collectors;

@Service
public class CommentService {
    private static final Logger logger = LoggerFactory.getLogger(CommentService.class);

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private UserService userService;

    /**
     * 列表查询
     */
    public void list(PageDTO pageDTO) {
        PageHelper.startPage(pageDTO.getPage(), pageDTO.getSize());
        CommentExample commentExample = new CommentExample();
        List<Comment> commentList = commentMapper.selectByExample(commentExample);
        PageInfo<Comment> pageInfo = new PageInfo<>(commentList);
        pageDTO.setTotal(pageInfo.getTotal());
        List<CommentDTO> commentDTOList = CopyUtil.copyList(commentList, CommentDTO.class);
        pageDTO.setList(commentDTOList);
    }

    /**
     * 保存，id有值时更新，无值时新增
     */
    public void save(CommentDTO commentDTO) {
        Comment comment = CopyUtil.copy(commentDTO, Comment.class);
        if (StringUtils.isEmpty(commentDTO.getId())) {
            this.insert(comment);
        } else {
            this.update(comment);
        }
    }

    /**
     * 新增
     */
    private void insert(Comment comment) {
        Date now = new Date();
        comment.setIsDeleted(DeletedStatusEnum.USED.getCode());
        comment.setCreateTime(now);
        comment.setUpdateTime(now);
        commentMapper.insert(comment);
    }

    /**
     * 更新
     */
    private void update(Comment comment) {
        comment.setUpdateTime(new Date());
        commentMapper.updateByPrimaryKey(comment);
    }

    /**
     * 删除
     */
    public void delete(Integer id) {
        CommentExample commentExample = new CommentExample();
        commentExample.createCriteria().andParentIdEqualTo(id);
        // 删除子评论
        commentMapper.deleteByExample(commentExample);
        commentMapper.deleteByPrimaryKey(id);
    }

    public List<CommentDTO> getByPostId(String postId) {
        CommentExample commentExample = new CommentExample();
        commentExample.createCriteria()
                .andPostIdEqualTo(postId)
                .andIsDeletedEqualTo(DeletedStatusEnum.USED.getCode());
        commentExample.setOrderByClause("create_time asc");
        List<Comment> commentList = commentMapper.selectByExample(commentExample);
        List<CommentDTO> commentDTOList = CopyUtil.copyList(commentList, CommentDTO.class);
        commentDTOList.forEach(commentDTO -> {
            String name = userService.getName(commentDTO.getUserId());
            if (commentDTO.getParentId() != 0) {
                // 设置父评论的用户昵称
                Comment comment = commentMapper.selectByPrimaryKey(commentDTO.getParentId());
                commentDTO.setParentCommentUserName(userService.getName(comment.getUserId()));
            }
            commentDTO.setCommentUserName(name);
        });
        return listWithTree(commentDTOList);
    }

    private List<CommentDTO> listWithTree(List<CommentDTO> commentDTOList) {
        return commentDTOList.stream()
                .filter(commentDTO -> commentDTO.getParentId() == 0)
                .peek(commentDTO -> commentDTO.setChildren(getChildrenComments(commentDTO, commentDTOList)))
                .collect(Collectors.toList());
    }

    private List<CommentDTO> getChildrenComments(CommentDTO root, List<CommentDTO> all) {
        return all.stream()
                .filter(commentDTO -> commentDTO.getParentId() == root.getId())
                .peek(commentDTO -> {
                    // 找到子评论（即回复）
                    commentDTO.setChildren(getChildrenComments(commentDTO, all));
                }).collect(Collectors.toList());
    }

    public void deleteByPostId(String postId) {
        CommentExample commentExample = new CommentExample();
        commentExample.createCriteria().andPostIdEqualTo(postId);
        int i = commentMapper.deleteByExample(commentExample);
        logger.info("已删除{}条评论", i);
    }
}
